﻿//     Copyright (c) Microsoft Corporation.  All rights reserved.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Gateway.Configuration;

namespace Microsoft.Gateway.RulesConfigurator
{
    public class ConfiguratorState
    {
        RulesConfiguration _cachedConfiguration;
        RulesConfiguration _newConfiguration;

        public ConfiguratorState(RulesConfiguration cachedConfiguration, RulesConfiguration newConfiguration)
        {
            this._cachedConfiguration = cachedConfiguration;
            this._newConfiguration = newConfiguration;
        }

        public bool RetryLater { get; set; }
        public bool UpdateCache { get; set; }
        public int FailedExitCode { get; set; }

        public ConfiguratorResults ApplyConfiguration<TComparitor>(Func<RulesConfiguration, ConfiguratorResults> applyConfiguration, int exitCode)
            where TComparitor : IEqualityComparer<RulesConfiguration>, new()
        {
            var comparitor = new TComparitor();
            if (!comparitor.Equals(this._newConfiguration, this._cachedConfiguration))
            {
                return ProcessResults(applyConfiguration(this._newConfiguration), exitCode);
            }
            return ConfiguratorResults.NoChange;
        }

        ConfiguratorResults ProcessResults(ConfiguratorResults result, int exitCode) 
        {
            switch (result)
            {
                case ConfiguratorResults.Failure:
                    // Failed already logged, throw an exception so that we skip applying any following configurations
                    this.FailedExitCode = exitCode;
                    throw new ApplicationException(exitCode.ToString());

                case ConfiguratorResults.RetryLater:
                    this.RetryLater = true;
                    break;

                case ConfiguratorResults.Success:
                    this.UpdateCache = true;
                    break;
            }
            return result;
        }
    }
}
